package _6_new_make

import (
	"fmt"
)

func TestMapDefine() {

	// 方式1：声明map类型的变量，此时没有初始化
	// var userInfo map[string]string // map类型的参数，只是做了声明，并没有初始化(没有申请内存)
	// userInfo["username"] = "ybxb"  // 到此步骤就会报错。
	// 报错的原因是：只对map进行了声明，并没有申请内存。
	// 如果要分配内存地址，要使用make
	// fmt.Println(userInfo)

	// 方式2:声明map类型的变量，并初始化
	var userInfo1 map[string]string = make(map[string]string)
	userInfo1["username"] = "ybxb"
	fmt.Println(userInfo1)

	// 方式3:声明并初始化
	var userInfo2 = map[string]string{}
	userInfo2["username"] = "张三"
	fmt.Println(userInfo2)
}

func TestMake() {
	// make方法：第一个参数是要初始化的引用类型(slice、map、channel),
	// 第二个参数是初始化的长度，第三个参数是初始化的容量，但元素进行初始化时，会把元素的值初始化成默认值
	var ints = make([]int, 3, 10)
	fmt.Printf("调用append方法之前的值是:%v\n", ints) // 打印结果是:[0 0 0]

	ints = append(ints, 1)
	fmt.Printf("类型是:%T,值是%v\n", ints, ints) // 打印结果：类型是:[]int, 值是[0 0 0 1]
	// 因为append方法是拼接到切片的最后，前面3个0，是因为使用make初始化时，指定了长度。
}

func TestMakeDefine() {
	// 1.声明一个长度为3,容量为10的元素为int类型的切片
	ints := make([]int, 3, 10)
	map1 := make(map[string]string, 10)
	ch1 := make(chan int, 10)
	fmt.Println(ints, map1, ch1) // 打印: [0 0 0] map[] 0xc000108000
}

// new函数返回是指针，是一个内存地址，而"="两边是值(不是内存地址)的赋值
func TestNew() {
	// new方法返回的是指针
	var ints = new([]int) // ints是一个内存地址，一般不会给内存地址直接赋值，而是给内存地址对应的变量赋值
	// append(ints, 1) // 因为new函数的返回值是指针类型，所以不能作为append函数的方法传入
	fmt.Printf("类型是:%T,值是%v\n", ints, ints) // 结果：类型是:*[]int,值是&[]
	*ints = append(*ints, 1)                // *ints获取指针指向变量的值，所以可以作为append函数的方法
	fmt.Printf("值是:%v", *ints)              // 值是:[1]
}

func TestNewDefine() {
	// 1.new实例化int类型
	var age = new(int)
	*age = 10                                    // 变量age是一个指针类型的变量
	fmt.Printf("age的类型是:%T, 值是:%v\n", age, *age) // age的类型是:*int, 值是:10

	// 2.new实例化切片
	var ints = new([]int)
	*ints = append(*ints, 1)
	fmt.Printf("ints的类型是:%T, 值是:%v\n", ints, *ints) // ints的类型是:*[]int, 值是:[1]

	// 3.new实例化map
	// 注意：new是申请一个块内存地址，但是内存地址存储的map是一个nil类型的Map
	var userInfo = new(map[string]string)
	fmt.Printf("userInfo的类型是:%T, 值是:%v\n", userInfo, *userInfo)

	fmt.Printf("userInfo是否为nil: %t\n", *userInfo == nil) // 结果为true

	// 所以还需要初始化一下userInfo这个map
	*userInfo = map[string]string{}
	(*userInfo)["username"] = "ybxb"
	fmt.Printf("userInfo的类型是:%T, 值是:%v\n", userInfo, *userInfo)
	// userInfo的类型是:*map[string]string, 值是:map[username:ybxb]
}
